﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml.Linq;
using Pavilion.DesignerTool.NodeDesignerTool.Scripting;

namespace Pavilion.DesignerTool
{
    public class NodeScriptWrapper
    {
        public event Action<NodeScriptWrapper> Disposed;

        public string Name { get { return NodeScript.Name; } set { SetName(value); } }
        public ContainerNodeWrapper RootContainerNodeWrapper { get; set; }
        public ResourceData ResourceData { get; private set; }
        public NodeScript NodeScript { get; set; }

        private string originalName;

        public NodeScriptWrapper(NodeScript nodeScript, ResourceData resourceData)
        {
            this.NodeScript = nodeScript;
            this.ResourceData = resourceData;
            this.originalName = Name;

            RootContainerNodeWrapper = new ContainerNodeWrapper(nodeScript.RootContainer, this);

            string nodeLayoutPath = GameEngine.NodeLayoutDirectory + ResourceData.ResourceName + @"\" + Name + ".xml";

            if (File.Exists(nodeLayoutPath))
                new NodeLayoutSerializer().DeserializeCollection(RootContainerNodeWrapper, nodeLayoutPath);
        }

        public void Dispose()
        {
            RootContainerNodeWrapper = null;
            ResourceData.ResourceItem.ObtainResourceCollection<NodeScriptCollection>().RemoveNodeScript(Name);

            OnDisposed();
            Disposed = null;
        }

        public void Save()
        {
            string nodeScriptPath = ResourceData.ResourceItem.ResourcePath + @"Node Scripts\";

            if (File.Exists(nodeScriptPath + originalName + ".xml"))
                File.Delete(nodeScriptPath + originalName + ".xml");

            if (!Directory.Exists(nodeScriptPath))
                Directory.CreateDirectory(nodeScriptPath);

            XDocument nodeScriptDocument = new ScriptXmlSerializer().SerializeScript(NodeScript);
            nodeScriptDocument.Save(nodeScriptPath + Name + ".xml");

            SaveNodeLayout();
        }

        private void SaveNodeLayout()
        {
            string nodeLayoutPath = ResourceData.NodeLayoutPath;
            XDocument nodeLayoutDocument = new NodeLayoutSerializer().SerializeCollection(RootContainerNodeWrapper);

            if (File.Exists(nodeLayoutPath + originalName + ".xml"))
                File.Delete(nodeLayoutPath + originalName + ".xml");

            if (!Directory.Exists(nodeLayoutPath))
                Directory.CreateDirectory(nodeLayoutPath);

            nodeLayoutDocument.Save(nodeLayoutPath + Name + ".xml");
        }

        public void DeleteXmlScript()
        {
            string nodeScriptPath = ResourceData.ResourceItem.ResourcePath + @"Node Scripts\";
            string nodeLayoutPath = ResourceData.NodeLayoutPath;

            if (File.Exists(nodeScriptPath + originalName + ".xml"))
                File.Delete(nodeScriptPath + originalName + ".xml");

            if (File.Exists(nodeScriptPath + Name + ".xml"))
                File.Delete(nodeScriptPath + Name + ".xml");

            if (File.Exists(nodeLayoutPath + originalName + ".xml"))
                File.Delete(nodeLayoutPath + originalName + ".xml");

            if (File.Exists(nodeLayoutPath + Name + ".xml"))
                File.Delete(nodeLayoutPath + Name + ".xml");
        }

        private void SetName(string value)
        {
            if (NodeScript.Name == value)
                return;

            string oldName = NodeScript.Name;
            NodeScript.Name = value;

            NodeScriptTransfer.Rename(ResourceData.ResourceName, oldName, value);
        }

        private void OnDisposed()
        {
            if (Disposed != null)
                Disposed(this);
        }
    }
}
